﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace TfsBacklogMgr.Tfs
{
    public class TfsConfig
    {
        TfsBacklogMgr.Main.IniFile _ini = null;
        const string MsfAgile = "MSF for Agile Software Development.ini";
        const string MsfScrum = "Visual Studio Scrum.ini";
        const string MsfCMMI = "MSF CMMI.ini";
        const string ScrumForTfs = "Scrum for TFS.ini";
        const string Codeplex = "Codeplex.ini";

        private TfsConfig(string configFilename)
        {
            _ini = new TfsBacklogMgr.Main.IniFile(configFilename);
        }

        private static TfsConfig _config = null;

        internal static TfsConfig GetTfsConfig()
        {
            return _config;
        }

        internal static TfsConfig GetTfsConfig(string configName)
        {
            if (_config != null)
                return _config;

            if (File.Exists(configName))
            {
                _config = new TfsConfig(configName);
            }
            return _config;
        }

        internal static TfsConfig GetTfsConfig(WorkItemTypeCollection workItemTypeCollection)
        {
            if (_config != null)
                return _config;

            string configName = "";
            bool hasPBI = false;
            bool hasSPT = false;
            bool hasTestCase = false;
            bool hasRequirement = false;
            bool hasSprint = false;
            bool hasUserStory = false;
            bool hasWorkItem = false;
            bool hasIssue = false;
            foreach (WorkItemType wit in workItemTypeCollection)
            {
                if (string.Compare(wit.Name, "Product Backlog Item", ignoreCase: true) == 0) hasPBI = true;
                if (string.Compare(wit.Name, "Sprint Backlog Task", ignoreCase: true) == 0) hasSPT = true;
                if (string.Compare(wit.Name, "Test Case", ignoreCase: true) == 0) hasTestCase = true;
                if (string.Compare(wit.Name, "Sprint", ignoreCase: true) == 0) hasSprint = true;
                if (string.Compare(wit.Name, "Requirement", ignoreCase: true) == 0) hasRequirement = true;
                if (string.Compare(wit.Name, "Issue", ignoreCase: true) == 0) hasIssue = true;
                if (string.Compare(wit.Name, "User Story", ignoreCase: true) == 0) hasUserStory = true;
                if (string.Compare(wit.Name, "Work Item", ignoreCase: true) == 0) hasWorkItem = true; 
            }

            if( hasWorkItem ) configName = Codeplex;
            if (hasRequirement) configName = MsfCMMI;
            if (hasUserStory && hasIssue && hasTestCase) configName = MsfAgile;
            if (hasPBI && hasSPT) configName = ScrumForTfs;
            if (hasPBI && ! hasSPT && hasSprint && hasTestCase ) configName = MsfScrum;


            if (string.IsNullOrEmpty(Path.Combine(configName)))
                configName = "Default.ini";

            if (!File.Exists(configName))
                configName = Path.Combine("Process Templates", configName);

            if (File.Exists(configName))
            {
                _config = new TfsConfig(configName);
            }
            return _config;
        }

        public string WITStory
        {
            get { return _ini.IniReadValue("WIT", "Story");  }
        }

        public string WITTask
        {
            get { return _ini.IniReadValue("WIT", "Task"); }
        }

        public string WITBug
        {
            get { return _ini.IniReadValue("WIT", "Bug"); }
        }


        public string StoryPoints
        {
            get { return _ini.IniReadValue("Field", "StoryPoints"); }
        }

        public string OrgEstimateHrs
        {
            get { return _ini.IniReadValue("Field", "OrgEstimate"); }
        }

        public string RemainingHrs
        {
            get { return _ini.IniReadValue("Field", "Remaining"); }
        }

        public bool HasStoryPoints
        {
            get { return string.IsNullOrWhiteSpace(StoryPoints); }
        }

        public bool HasOrgEstimateHrs
        {
            get { return string.IsNullOrWhiteSpace(OrgEstimateHrs); }
        }

        public bool HasRemainingHrs
        {
            get { return string.IsNullOrWhiteSpace(RemainingHrs); }
        }


        public int StoryPointsPrecision
        {
            get { return _ini.IniReadInt("Decimals", "StoryPoints"); }
        }

        public int OrgEstimateHrsPrecision
        {
            get { return _ini.IniReadInt("Decimals", "OrgEstimate"); }
        }

        public int RemainingHrsPrecision
        {
            get { return _ini.IniReadInt("Decimals", "Remaining"); }
        }


    }
}
